package com.asdhawaii.otello.players;

import java.util.ArrayList;
import java.util.List;
import com.asdhawaii.otello.board.Move;
import com.asdhawaii.otello.board.Square;
import com.asdhawaii.otello.board.SquareContents;

/**
 * A mid-level Otello AI that focuses on obtaining corners.
 * 
 * @author Branden Ogata
 *
 */

public class Level2Ai extends AbstractOtelloAi
{
  /**
   * Creates a new Level2Ai.
   * 
   * @param color The SquareContents indicating the color of the pieces for the new Level2Ai.
   * 
   */
  
  public Level2Ai(SquareContents color)
  {
    super(color);
  }

  /**
   * Returns the move or one of the moves that this AI finds the best out of the available moves.
   * 
   * This generally follows what Level1Ai would do unless a move is on a special square:
   *  |0|1|2|3|4|5|6|7|
   *  .-.-.-.-.-.-.-.-.
   * 0|!|C|A| | |A|C|!|
   * -.-.-.-.-.-.-.-.-.
   * 1|C|X| | | | |X|C|
   * -.-.-.-.-.-.-.-.-.
   * 2|A| | | | | | |A|
   * -.-.-.-.-.-.-.-.-. !: Corner; should take immediately
   * 3| | | | | | | | | C: Next to corner; should not take since this opens corner to opponent
   * -.-.-.-.-.-.-.-.-. X: Next to corner on diagonal; should not take as above and because 
   * 4| | | | | | | | |    long diagonal is very vulnerable as pieces will always be there 
   * -.-.-.-.-.-.-.-.-. A: Two away from corner; should move here since flip requires enemy on C
   * 5|A| | | | | | |A|
   * -.-.-.-.-.-.-.-.-.
   * 6|C|X| | | | |X|C|
   * -.-.-.-.-.-.-.-.-.
   * 7|!|C|A| | |A|C|!|
   * -.-.-.-.-.-.-.-.-.
   * 
   * The restrictions on C and X squares should be ignored if this AI already has a piece on the
   * adjacent corner since the opponent would no longer be able to acquire the corner.
   * 
   * @param board The Square[][] representing the Otello board.
   * @param moves The List<Move> containing the valid moves on the board.
   * 
   * @return selection A Move representing the move that this Level2Ai chose.
   * 
   */
  
  @Override
  public Move getMove(Square[][] board, List<Move> moves)
  {
    List<Move> candidates = new ArrayList<Move>();
    List<Move> corners = AiStrategies.getCorners(board, moves, this.getColor());
    List<Move> contiguousC = AiStrategies.getContiguousCSquares(board, moves, this.getColor());
    List<Move> contiguousX = AiStrategies.getContiguousXSquares(board, moves, this.getColor());
    List<Move> aSquares = AiStrategies.getASquares(board, moves, this.getColor());
    List<Move> cSquares = AiStrategies.getCSquares(board, moves, this.getColor());
    List<Move> xSquares = AiStrategies.getXSquares(board, moves, this.getColor());
        
    // If there are corners available
    if (!corners.isEmpty())
    {
      candidates.addAll(corners);
    }
    
    // Else if there are squares adjacent to own corners available
    else if (!contiguousC.isEmpty())
    {      
      candidates.addAll(contiguousC);
    }
    else if (!contiguousX.isEmpty())
    {      
      candidates.addAll(contiguousX);
    }
    
    // Else if there are A squares available
    else if (!aSquares.isEmpty())
    {
      candidates.addAll(aSquares);
    }
    
    // Else remove C, X squares from candidates before applying maxima
    else
    {
      candidates.addAll(moves);
      candidates.removeAll(cSquares);
      candidates.removeAll(xSquares);
      
      // If no valid moves with that restriction, then prefer C over X squares
      if (candidates.isEmpty())
      {
        candidates.addAll(cSquares);
        
        if (candidates.isEmpty())
        {
          candidates.addAll(xSquares);
        }
      }
    }
    
    return AiStrategies.random(AiStrategies.maxima(board, candidates, this.getColor()));
  }
}